Repository navigation
fix(core): Avoid stack overflow in FunctionToString on cyclic Proxy prototype chains - #26162
Conversation
…rototype chains The patched toString read __sentry_original__ through the prototype chain. When that chain loops back through a Proxy, the lookup never ends and overflows the stack, while native toString returns normally. Only unwrap when the original is an own property, which is how markFunctionWrapped stores it, and fall back to native toString if the lookup throws. The Hono proxies exposed __sentry_original__ only through a get trap, so they also report it as an own property now to keep unwrapping. Fixes #25963 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 3079ba0. Configure here.
size-limit report 📦Compared: 840f27e (PR test merge using develop at 4c9a4eb) Against: 4c9a4eb (develop) · base run #65205 ✅ Baseline matches: this diff contains only this PR's changes.
|
Optional E2E testsSome optional checks were not successful. They do not block the merge. 6 not successful, 50 successful. See the run.
Successful checks
|
andreiborza
left a comment
There was a problem hiding this comment.
I'd just inline this and avoid the extra function and the eslint disabling
| unwrappedFunction = originalFunction; | ||
| // `markFunctionWrapped` sets the original as an own property. An inherited lookup could walk a | ||
| // prototype chain that loops through a Proxy and overflow the stack, which native `toString` never does. | ||
| if (SETUP_CLIENTS.has(getClient() as Client) && hasOwnProperty(this, '__sentry_original__')) { |
There was a problem hiding this comment.
| if (SETUP_CLIENTS.has(getClient() as Client) && hasOwnProperty(this, '__sentry_original__')) { | |
| if (SETUP_CLIENTS.has(getClient() as Client) && Object.prototype.hasOwnProperty.call(this, '__sentry_original__')) { |
There was a problem hiding this comment.
This brings back the exact issue we gave as the reason for closing #25964
| // eslint-disable-next-line @typescript-eslint/unbound-method | ||
| const hasOwnProperty = Function.prototype.call.bind(Object.prototype.hasOwnProperty) as ( | ||
| obj: unknown, | ||
| key: PropertyKey, | ||
| ) => boolean; |
There was a problem hiding this comment.
| // eslint-disable-next-line @typescript-eslint/unbound-method | |
| const hasOwnProperty = Function.prototype.call.bind(Object.prototype.hasOwnProperty) as ( | |
| obj: unknown, | |
| key: PropertyKey, | |
| ) => boolean; |
Why: The patched
toStringlooked up__sentry_original__through the prototype chain. If that chain loops through a Proxy, the lookup overflows the stack, while nativetoStringworks fine. We now only read it when it's an own property, which is wheremarkFunctionWrappedputs it.The Hono proxies only exposed it through a
gettrap, so they now report it as an own property too.Closes #25963